﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NewRetail.Application.Components.Goods.Entity;
using NewRetail.Application.Components.Warehouse;
using NewRetail.Application.Components.Warehouse.Entity;
using NewRetail.Application.Components.Warehouse.Model;
using NewRetail.Application.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;

namespace NewRetail.Api.Controllers
{
    [NewRetailRoute("warehouse-goods")]
    public class WarehouseGoodsController : BaseController<WarehouseGoods, WarehouseGoodsPagingRequestDto>
    {
        private readonly IWarehouseGoodsService warehouseGoodsService;

        public WarehouseGoodsController(IWarehouseGoodsService warehouseGoodsService)
        {
            this.warehouseGoodsService = warehouseGoodsService;
        }

        [HttpPost("update-warehouse-goods-status")]
        public async Task<ResponseEntity<object>> UpdateWarehouseGoodsStatus([FromBody] UpdateWarehouseGoodsStatusDto[] dto)
        {
            await this.warehouseGoodsService.UpdateWarehouseGoodsStatus(dto);

            return new ResponseEntity<object>().SetSuccess();
        }

        protected override async Task<IQueryable<WarehouseGoods>> OrderQueryPaging(IQueryable<WarehouseGoods> query, WarehouseGoodsPagingRequestDto dto)
        {
            await Task.CompletedTask;

            query = query.OrderByDescending(x => x.goodsNum);
            return query;
        }

        protected override async Task<IQueryable<WarehouseGoods>> FilterQueryPaging(DbContext db, IQueryable<WarehouseGoods> query, WarehouseGoodsPagingRequestDto dto)
        {
            if (!string.IsNullOrWhiteSpace(dto.supplierId))
            {
                var warehouseGoodsIdQuery = from warehouseGoods in db.Set<WarehouseGoods>().AsNoTracking()
                                            join inoutWarehouse in db.Set<InOutWarehousing>().AsNoTracking().DefaultIfEmpty()
                                            on new { warehouseGoods.warehouseID, warehouseGoods.goodsID } equals
                                            new { inoutWarehouse.warehouseID, inoutWarehouse.goodsID }
                                            where inoutWarehouse.supplierID == dto.supplierId
                                            select warehouseGoods.Id;

                query = query.Where(x => warehouseGoodsIdQuery.Contains(x.Id));
            }
            //添加仓库id
            var warehouseIds = Array.Empty<string>();
            if (dto.HasWarehouseCondition())
            {
                var warehouseQuery = db.Set<Warehouse>().AsNoTracking();
                if (!string.IsNullOrWhiteSpace(dto.warehouseName))
                {
                    warehouseQuery = warehouseQuery.Where(x => x.warehouseName.Contains(dto.warehouseName));
                }
                if (!string.IsNullOrWhiteSpace(dto.warehouseNo))
                {
                    warehouseQuery = warehouseQuery.Where(x => x.No.Contains(dto.warehouseNo));
                }

                var ids = warehouseQuery.Select(x => x.Id);
                query = query.Where(x => ids.Contains(x.warehouseID));
                //这边赋值后需要给到分类条件用，因为分类No由于不同仓库可能会相同。
                warehouseIds = ids.ToArray();
            }

            if (dto.HasGoodsCondition())
            {
                var goodsQuery = db.Set<GoodsInfo>().AsNoTracking();

                if (!string.IsNullOrWhiteSpace(dto.goodsName))
                {
                    goodsQuery = goodsQuery.Where(x => x.goodsName.Contains(dto.goodsName));
                }

                if (!string.IsNullOrWhiteSpace(dto.goodsNo))
                {
                    goodsQuery = goodsQuery.Where(x => x.No.Contains(dto.goodsNo));
                }

                if (!string.IsNullOrWhiteSpace(dto.goodsBarCode))
                {
                    goodsQuery = goodsQuery.Where(x => x.barCode.Contains(dto.goodsBarCode));
                }

                //添加商品建档日期的条件
                if (dto.createDate != null)
                {
                    var start = dto.createDate.Value.Date;
                    //var end = DateTime.Now.AddDays(1);
                    //goodsQuery = goodsQuery.Where(x => x.addTime >= start && x.addTime < end);
                    goodsQuery = goodsQuery.Where(x => x.addTime >= start);
                }
                if (dto.createDateEnd != null)
                {
                    var end = dto.createDate.Value.Date.AddDays(1);
                    goodsQuery = goodsQuery.Where(x => x.addTime < end);
                }

                if (!string.IsNullOrWhiteSpace(dto.categoryNo))
                {
                    var categorys = Array.Empty<GoodsCategory>();
                    //由于不同仓库分类No会重复，因此不能获取第一个
                    if (warehouseIds.Length > 0)
                        categorys = await db.Set<GoodsCategory>().AsNoTracking().Where(x => x.No == dto.categoryNo && warehouseIds.Contains(x.warehouseID)).ToArrayAsync();
                    else
                        categorys = await db.Set<GoodsCategory>().AsNoTracking().Where(x => x.No == dto.categoryNo).ToArrayAsync();
                    if (categorys.Length > 0)
                    {
                        var gcIds = categorys.Select(x => x.Id);
                        goodsQuery = goodsQuery.Where(x => gcIds.Contains(x.categoryID));
                    }
                    //if (category != null)
                    //{
                    //    goodsQuery = goodsQuery.Where(x => x.categoryID == category.Id);
                    //}
                    //var category = await db.Set<GoodsCategory>().AsNoTracking().FirstOrDefaultAsync(x => x.No == dto.categoryNo);
                    //if (category != null)
                    //{
                    //    goodsQuery = goodsQuery.Where(x => x.categoryID == category.Id);
                    //}
                }

                var ids = goodsQuery.Select(x => x.Id);
                query = query.Where(x => ids.Contains(x.goodsID));
            }

            //添加是否打折条件
            if (!string.IsNullOrWhiteSpace(dto.isDiscount))
            {
                if(dto.isDiscount == "0")
                    query = query.Where(x => x.isDiscount == false);
                else if(dto.isDiscount == "1")
                    query = query.Where(x => x.isDiscount == true);
            }

            var allGoodsIds = db.Set<GoodsInfo>().AsNoTracking().Select(x => x.Id);
            query = query.Where(x => allGoodsIds.Contains(x.goodsID));
            //库存量条件
            if (dto.lowerQuantity != null)
                query = query.Where(x => x.goodsNum >= dto.lowerQuantity);
            if (dto.upperQuantity != null)
                query = query.Where(x => x.goodsNum <= dto.upperQuantity);

            return await base.FilterQueryPaging(db, query, dto);
        }

        public override async Task<ResponseEntity<PagedResultDto<WarehouseGoods>>> QueryPaging([FromBody] WarehouseGoodsPagingRequestDto dto)
        {
            var res = await base.QueryPaging(dto);

            if (res?.Data?.Items?.Any() ?? false)
            {
                res.Data.Items = await this.warehouseGoodsService.AttachWarehouse(res.Data.Items.ToArray());
                res.Data.Items = await this.warehouseGoodsService.AttachGoodsInfo(res.Data.Items.ToArray());
                #region 添加类别和供应商
                res.Data.Items = await this.warehouseGoodsService.AttachSupplier(res.Data.Items.ToArray());
                #endregion
            }

            return res;
        }

        [HttpPost("approve-change-warehouse")]
        public async Task<ResponseEntity<object>> ApproveChangeWarehouse([FromBody] ChangeWarehouseDto dto)
        {
            await this.warehouseGoodsService.ApproveChangeWarehouse(dto);
            return new ResponseEntity().SetSuccess();
        }

        [HttpPost("revoke-change-warehouse")]
        public async Task<ResponseEntity<object>> RevokeChangeWarehouse([FromBody] ChangeWarehouseDto dto)
        {
            await this.warehouseGoodsService.RevokeChangeWarehouse(dto);
            return new ResponseEntity().SetSuccess();
        }

        [HttpPost("approve-check-stock")]
        public async Task<ResponseEntity<object>> ApproveCheckStock([FromBody] CheckStockDto dto)
        {
            await this.warehouseGoodsService.ApproveCheckStock(dto);
            return new ResponseEntity().SetSuccess();
        }

        [HttpPost("revoke-check-stock")]
        public async Task<ResponseEntity<object>> RevokeCheckStock([FromBody] CheckStockDto dto)
        {
            await this.warehouseGoodsService.RevokeCheckStock(dto);
            return new ResponseEntity().SetSuccess();
        }

        [HttpPost("approve-inout-warehouse")]
        public async Task<ResponseEntity<object>> ApproveInoutWarehouse([FromBody] InoutWarehouseDto dto)
        {
            await this.warehouseGoodsService.ApproveInoutWarehouse(dto);
            return new ResponseEntity().SetSuccess();
        }

        [HttpPost("revoke-inout-warehouse")]
        public async Task<ResponseEntity<object>> RevokeInoutWarehouse([FromBody] InoutWarehouseDto dto)
        {
            var ret = await this.warehouseGoodsService.RevokeInoutWarehouse(dto);
            var result = new ResponseEntity();
            if (string.IsNullOrEmpty(ret))
                return result.SetSuccess();
            else
                return new ResponseEntity().SetError(ret);
        }

        [HttpPost("approve-adjust-price")]
        public async Task<ResponseEntity<object>> ApproveAdjustPrice([FromBody] AdjustPriceDto dto)
        {
            await this.warehouseGoodsService.ApproveAdjustPrice(dto);
            return new ResponseEntity().SetSuccess();
        }

        [HttpPost("revoke-adjust-price")]
        public async Task<ResponseEntity<object>> RevokeAdjustPrice([FromBody] AdjustPriceDto dto)
        {
            await this.warehouseGoodsService.RevokeAdjustPrice(dto);
            return new ResponseEntity().SetSuccess();
        }

        #region add by cl 
        /// <summary>
        /// 审核
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("approve-other-bill")]
        public async Task<ResponseEntity<object>> ApproveOtherBill([FromBody] OtherBillDto dto)
        {
            await this.warehouseGoodsService.ApproveOtherBill(dto);
            return new ResponseEntity().SetSuccess();
        }
        /// <summary>
        /// 弃审
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("revoke-other-bill")]
        public async Task<ResponseEntity<object>> RevokeOtherBill([FromBody] OtherBillDto dto)
        {
            await this.warehouseGoodsService.RevokeOtherBill(dto);
            return new ResponseEntity().SetSuccess();
        }
        #endregion

        #region add by cl 
        /// <summary>
        /// 次品单审核
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("approve-defective-bill")]
        public async Task<ResponseEntity<object>> ApproveDefectiveBill([FromBody] DefectiveBillDto dto)
        {
            await this.warehouseGoodsService.ApproveDefectiveBill(dto);
            return new ResponseEntity().SetSuccess();
        }
        /// <summary>
        /// 次品单弃审
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("revoke-defective-bill")]
        public async Task<ResponseEntity<object>> RevokeDefectiveBill([FromBody] DefectiveBillDto dto)
        {
            await this.warehouseGoodsService.RevokeDefectiveBill(dto);
            return new ResponseEntity().SetSuccess();
        }
        #endregion

        #region add by cl 20220729

        #region 类别库存查询
        [HttpPost("query-categorywarehousegood")]
        public async Task<ResponseEntity<IEnumerable<CategoryWarehouseGoodShowDto>>> QueryCategoryWarehouseGood([FromBody] QueryCategoryWarehouseGoodDto inputDto)
        {
            var ret = new ResponseEntity<IEnumerable<CategoryWarehouseGoodShowDto>>();
            try
            {
                var result = await this.warehouseGoodsService.GetCategoryWarehouseGoodInfo(inputDto);
                ret.SetData(result);
            }
            catch (Exception e)
            {
                ret.SetError("失败！" + e.Message);
            }

            return ret;
        }
        #endregion

        #region 类别实时库存查询
        [HttpPost("query-categoryrealwarehousegood")]
        public async Task<ResponseEntity<PagedResultDto<CategoryRealWarehouseGoodShowDto>>> QueryCategoryRealWarehouseGood([FromBody] WarehouseGoodsPagingRequestDto inputDto)
        {
            var ret = new ResponseEntity<PagedResultDto<CategoryRealWarehouseGoodShowDto>>();
            try
            {
                var result = await this.warehouseGoodsService.GetCategoryRealWarehouseGoodInfo(inputDto);
                ret.SetData(result);
            }
            catch (Exception e)
            {
                ret.SetError("失败！" + e.Message);
            }

            return ret;
        }
        #endregion

        #endregion
    }
}
